import React from 'react';

import { ReactComponent as CloseCircle } from '@/assets/images/auth/CloseCircle.svg';
import { Container } from '@/entities/auth';
import { authByEmail, clearAuthByEmailStatus, clearEmailStatus, setCheckAuth } from '@/entities/auth/model/actions';
import { getAuthProcessEmail, getEmailAuthError } from '@/entities/auth/model/selectors';
import { getProfile } from '@/entities/profile/model/actions';
import { BackButton } from '@/features/BackButton';
import { innerUrls } from '@/shared/constants';
import { useKeyboard } from '@/shared/lib/hooks';
import { useAppDispatch, useAppSelector } from '@/shared/store';
import { Button, ButtonVariants, FlexWrapper, Input, Snackbar, Title } from '@/shared/ui';
import { jwtDecode } from 'jwt-decode';
import { useRouter } from 'next/router';
import { useSnackbar } from 'notistack';
import { useWindowSize } from 'usehooks-ts';

import { ForgotPassword } from '../ui/ForgotPassword';
import { Overlay } from '../ui/Overlay';
import s from './PasswordPage.module.scss';

export const PasswordPage = () => {
  const email = useAppSelector(getAuthProcessEmail);

  const { width } = useWindowSize();

  const [password, setPassword] = React.useState<string>(''); // пароль для авторизации или регистрации
  const [isPasswordHidden, setPasswordHidden] = React.useState<boolean>(true); // состояние скрытого пароля
  const [isForgot, setIsForgot] = React.useState<boolean>(false);
  const [isCorrectPassword, setIsCorrectPassword] = React.useState<boolean>(true);
  const { enqueueSnackbar } = useSnackbar();
  const handleForgot = () => {
    setIsForgot(true);
  };
  const emailAuthError = useAppSelector(getEmailAuthError);

  const dispatch = useAppDispatch();
  const router = useRouter();

  const handleSetPassword = (event: React.ChangeEvent<HTMLInputElement>) => {
    setIsCorrectPassword(true);
    const { value } = event.target;
    setPassword(value);
  };

  const handleAuth = async () => {
    try {
      if (password.length < 6) {
        setIsCorrectPassword(false);
        return;
      }

      const res = await dispatch(authByEmail({ email, password } as { email: string; password: string }));
      if (res.meta.requestStatus !== 'rejected') {
        const decodedToken: {
          email?: string;
          exp: number;
          iat: string;
          shi: any[];
          sub: number;
          // @ts-ignore
        } = jwtDecode(res.payload.accessToken);
        dispatch(setCheckAuth({ userId: decodedToken.sub, email: decodedToken?.email, expiresIn: decodedToken.exp }));
        dispatch(getProfile(decodedToken.sub)).then(() => {
          enqueueSnackbar('Успешно авторизован', {
            variant: 'success',
            content: (key, message) => <Snackbar id={key} message={message} size="md" variant="success" />,
          });
          router.replace(innerUrls.main);
        });
      }
    } catch (error) {
      dispatch(clearAuthByEmailStatus());
    }
  };
  useKeyboard('Enter', () => {
    if (router.asPath === innerUrls.auth.password) {
      handleAuth;
    }
  });

  React.useEffect(() => {
    if (emailAuthError === 'Wrong password') {
      setIsCorrectPassword(false);
    }
  }, [emailAuthError]);

  const handleGoBack = () => {
    dispatch(clearEmailStatus());
    router.push(innerUrls.auth.email);
  };

  const handleSetIsForgot = () => {
    setIsForgot(false);
  };

  React.useEffect(() => {
    if (!email) {
      handleGoBack();
      return;
    }
    if (width > 768) {
      document.body.style.overflow = 'hidden';
    }

    return () => {
      document.body.style.overflow = 'auto';
    };
  }, []);

  useKeyboard('Escape', handleGoBack);
  useKeyboard('Enter', handleAuth);

  return (
    <>
      {isForgot && <ForgotPassword setIsForgot={handleSetIsForgot} />}
      <Overlay>
        <Container isVisible={isForgot && width > 768}>
          <div className={s.closeCircle} onClick={handleGoBack}>
            <CloseCircle />
          </div>
          <FlexWrapper gap={8} isCenter>
            <BackButton className={s.goBack} onClick={handleGoBack} />
            <Title className={s.inside} size="l" tag="h1">
              Вход
            </Title>
            <p className={s.email}>{email}</p>
          </FlexWrapper>
          <FlexWrapper className={s.input} isModalWidth>
            <h6 className={s.password}>Пароль</h6>

            <Input
              data-testid="input-password"
              handleHidePassword={() => setPasswordHidden(false)}
              handleShowPassword={() => setPasswordHidden(true)}
              hidden={isPasswordHidden}
              htmlFor="authPassword"
              id="authPassword"
              isAutoFocus={width > 768 && password.length === 0}
              isNotAccepted={!isCorrectPassword}
              isNotAcceptedText="Неверный пароль"
              isPasswordField
              onChange={handleSetPassword}
              type={isPasswordHidden ? 'password' : 'text'}
              value={password}
            />
          </FlexWrapper>

          <Button
            data-testid="button-auth"
            disabled={password.length === 0 || isCorrectPassword === false}
            onClick={handleAuth}
            variant={ButtonVariants.Primary}
          >
            Войти
          </Button>
          <Button
            className={s.forgot}
            data-testid="button-forget_password"
            onClick={handleForgot}
            variant={ButtonVariants.Link}
          >
            Забыли пароль?
          </Button>
        </Container>
      </Overlay>
    </>
  );
};
